#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
@File   : login.py
@Time : 2024/12/6 15:59
@Author: Wangwc
@Describe:  ……
"""

import requests

from commons.logger import log
from utils.encrypt_tools import DataEncrypt
from utils.config_tools import Config
from utils.requests_tools import HttpRequest
from utils.requests_tools import check_response

assert_message = {'code': 200, 'msg': 'success'}


class Login:
    def __init__(self, user="user",config_name = "cloud.ini"):
        self.user = user
        self.config_name = config_name
        """
        :param user: storage.ini配置文件中user节点的用户名,默认为user,也可以传入其他节点的用户名
        """
        self.hostname = Config(self.config_name).read_config_ini('envHost', 'hostname')
        self.username = Config(self.config_name).read_config_ini(self.user,'user_name')
        self.raw_password = Config(self.config_name).read_config_ini(self.user,'user_pwd')
        self.data_encrypt = DataEncrypt()  # 实例化DataEncrypt对象，方便后续复用
        self.http_request = HttpRequest(self.config_name)  # 实例化HttpRequest对象，方便后续复用

    def _is_request_successful(self, response):
        """
        判断请求是否成功（状态码在200 - 299区间）
        :param response: requests库的响应对象
        :return: 布尔值，表示请求是否成功
        """
        return 200 <= response.status_code < 300

    def verify_check(self,username=None):
        """获取公钥接口"""
        path = '/ugreen/v1/verify/check'
        data = {
            "username": self.username if username is None else username
        }
        try:
            result = self.http_request.post(path, json=data)
            return result.headers.get('X-Rsa-Token') if self._is_request_successful(result) else None
        except requests.ConnectionError as e:
            log.error(f"网络连接出现问题，获取公钥请求失败: {e}")
            raise  # 可以选择抛出，或者根据需要返回合适的值并记录日志，这里选择抛出以便上层处理
        except requests.Timeout as e:
            log.error(f"获取公钥请求超时: {e}")
            raise
        except Exception as e:
            log.error(f"获取公钥接口出现其他异常: {e}")
            raise

    def login(self,username=None, password=None):
        """
        重新封装一个登录方法，根据选择config.ini里面的user账号登录
        :return:
        """
        path = '/ugreen/v1/verify/login'
        # 登录前置步骤，用名户拿到公钥
        Rsa_Token = self.verify_check()
        if Rsa_Token is None:
            log.error("获取公钥失败，无法进行登录操作")
            return None
        try:
            encrypted_passwd = self.data_encrypt.rsa_passwd(Rsa_Token, self.raw_password)
            data_login = {
                "username": self.username if username is None else username,
                "password": encrypted_passwd if password is None else password,
            }
            response = self.http_request.post(path, json=data_login)
            log.debug(f"这里获取到的响应结果为：{response}")
            if self._is_request_successful(response):
                try:
                    token = response.json().get('data').get('token')
                    log.info(f"登录成功，获取到的token: {token}")
                    if token:
                        return token
                    log.warning(f"没有获取到token信息，直接返回json数据: {response.json()}")
                    return response.json()
                except ValueError as json_error:
                    log.error(f"响应数据无法解析为JSON格式，无法获取token: {json_error}")
                    return response
            else:
                log.error(f"登录请求失败，状态码: {response.status_code}")
                return None
        except requests.ConnectionError as e:
            log.error(f"网络连接出现问题，登录过程出现异常: {e}")
            raise
        except requests.Timeout as e:
            log.error(f"登录请求超时: {e}")
            raise
        except Exception as e:
            log.error(f"登录过程出现其他异常: {e}")
            raise

    # @check_response的就是一个装饰器，就用校验结果和拿对应的数据，如果不用的话就要自己写断言逻辑
    @check_response(ext="data", check=assert_message)
    def gernaral_login(self,username=None, password=None):
        """
        重新封装一个登录方法，根据选择config.ini里面的user账号登录
        :return:
        """
        path = '/ugreen/v1/verify/login'
        Rsa_Token = self.verify_check()
        if Rsa_Token is None:
            log.error("获取公钥失败，无法进行登录操作")
            return None
        try:
            encrypted_passwd = self.data_encrypt.rsa_passwd(Rsa_Token, self.raw_password)
            data_login = {
                "username": self.username if username is None else username,
                "password": encrypted_passwd if password is None else password,
            }
            response = self.http_request.post(path, json=data_login)
            return response
        except requests.ConnectionError as e:
            log.error(f"网络连接出现问题，登录过程出现异常: {e}")
            raise
        except requests.Timeout as e:
            log.error(f"登录请求超时: {e}")
            raise
        except Exception as e:
            log.error(f"登录过程出现其他异常: {e}")
            raise

    def get_curpass_token(self) -> str:
        """
        直接根据登录用户获取x-curpass-token信息

        :return: 返回x-curpass-token
        """
        log.info("开始获取x-curpass-token信息，进入 get_curpass_token 方法")
        try:
            log.info("开始调用Login().verify_check()获取X_Rsa_Token信息")
            X_Rsa_Token = self.verify_check()
            log.info(f"成功获取X_Rsa_Token信息，值为: {X_Rsa_Token}")
            log.info("开始调用Config().read_config_ini('user', 'user_pwd')获取用户密码")
            usr_passwd = self.raw_password
            log.info(f"成功获取用户密码，值为: {usr_passwd}")
            log.info("开始调用data_encrypt.rsa_passwd(X_Rsa_Token, usr_passwd)对密码进行加密")
            x_curpass_token = self.data_encrypt.rsa_passwd(X_Rsa_Token, usr_passwd)
            log.info(f"成功获取x-curpass-token信息，加密后的密码串为: {x_curpass_token}")
            return x_curpass_token
        except Exception as e:
            log.error(f"在获取x-curpass-token信息过程中出现异常，异常信息: {e}", exc_info=True)
            raise
        finally:
            log.info("获取x-curpass-token信息的操作已完成")

if __name__ == "__main__":
    a = Login().login()
    print(a)
